package utils.file;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件上传处理类
 */
public class FileUtils {

    private static final Log log = LogFactory.getLog(FileUtils.class);

    public static Map<String, Object> upload(MultipartFile[] uploadFiles, String filePath) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        String fileName = null;
        for (MultipartFile uploadFile : uploadFiles) {
            if (uploadFile.isEmpty()) {
                resultMap.clear();
                resultMap.put("success", false);
                return resultMap;
            } else {
                fileName = uploadFile.getOriginalFilename();
                log.debug("文件原名: " + fileName);
                log.debug("文件长度: " + uploadFile.getSize());
                log.debug("文件类型: " + uploadFile.getContentType());
                log.debug("========================================");
                try {
                    org.apache.commons.io.FileUtils.copyInputStreamToFile(uploadFile.getInputStream(), new File(filePath, fileName));
                } catch (IOException e) {
                    log.debug("文件[" + fileName + "]上传失败,错误为:", e);
                    resultMap.clear();
                    resultMap.put("success", false);
                    return resultMap;
                }
            }
            resultMap.clear();
            resultMap.put("success", true);
            return resultMap;
        }
        resultMap.put("success", false);
        resultMap.put("info", "无上传文件");
        return resultMap;
    }

    /**
     * 迭代指定路径下所有zip包放入list
     *
     * @param strPath
     * @return
     */
    public static List<File> getFileList(String strPath) {
        File[] files = new File(strPath).listFiles(); // 该文件目录下文件全部放入数组
        List<File> fileList = new ArrayList<File>();
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                String fileName = files[i].getName();
                if (files[i].isDirectory()) { // 判断是文件还是文件夹
                    getFileList(files[i].getAbsolutePath()); // 获取文件绝对路径
                } else if (fileName.endsWith("zip")) { // 判断文件名是否以.zip结尾
                    String strFileName = files[i].getAbsolutePath();
                    log.debug("---" + strFileName);
                    fileList.add(files[i]);
                } else {
                    continue;
                }
            }

        }
        return fileList;
    }

    /**
     * 迭代指定路径下所有文件夹，以File存入List
     *
     * @param strPath 指定路径
     * @return
     */
    public static List<File> getDirectoryList(String strPath) {
        File[] files = new File(strPath).listFiles();
        List<File> fileList = new ArrayList<File>();
        if (files != null) {
            for (File fileObj : files) {
                if (fileObj.isDirectory()) {
                    fileList.add(fileObj);
                }
            }
        }
        return fileList;
    }


    /**
     * 将文件头转换成16进制字符串
     *
     * @param
     * @return 16进制字符串
     */
    private static String bytesToHexString(byte[] src) {

        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * 得到文件头
     *
     * @return 文件头
     * @throws IOException
     */
    private static String getFileContent(InputStream inputStream) throws IOException {

        byte[] b = new byte[28];
        try {

            inputStream.read(b, 0, 28);
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } /*finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        }*/
        return bytesToHexString(b);
    }

    public static Boolean verifyType(MultipartFile multipartFile, FileType... fileTypes){
        try {
            return verifyType(multipartFile.getInputStream(), fileTypes);
        } catch (IOException e) {
            log.error("文件校验出错，异常为:", e);
            return false;
        }
    }

    /**
     * 判断文件类型
     *
     * @return 文件类型
     */
    public static Boolean verifyType(InputStream inputStream, FileType... fileTypes) {
        try {
            String fileHead = getFileContent(inputStream);

            if (fileHead == null || fileHead.length() == 0) {
                return false;
            }

            fileHead = fileHead.toUpperCase();
            for (FileType type : fileTypes) {
                if (fileHead.startsWith(type.getValue())) {
                    return true;
                }
            }
        }catch (IOException e){
            log.error("文件校验出错，异常为:", e);
            return false;
        }

        return false;
    }


  public   enum FileType {
        JPEG("FFD8FF"),
        PNG("89504E47"),
        GIF("47494638"),
        TIFF("49492A00"),
        BMP("424D"),
        DWG("41433130"),
        PSD("38425053"),
        RTF("7B5C727466"),
        XML("3C3F786D6C"),
        HTML("68746D6C3E"),
        EML("44656C69766572792D646174653A"),
        DBX("CFAD12FEC5FD746F"),
        PST("2142444E"),
        XLS_DOC("D0CF11E0"),
        MDB("5374616E64617264204A"),
        WPD("FF575043"),
        EPS("252150532D41646F6265"),
        PDF("255044462D312E"),
        QDF("AC9EBD8F"),
        PWL("E3828596"),
        ZIP("504B0304"),
        RAR("52617221"),
        WAV("57415645"),
        AVI("41564920"),
        RAM("2E7261FD"),
        RM("2E524D46"),
        MPG("000001BA"),
        MOV("6D6F6F76"),
        ASF("3026B2758E66CF11"),
        MID("4D546864");

        private String fileType;


        private FileType(String fileType) {
            this.fileType = fileType;
        }

        public String getValue() {
            return fileType;
        }

        public void setValue(String fileType) {
            this.fileType = fileType;
        }

    }


}
